class Compiler {
    constructor (vm) {
        this.$vm = vm
        this.$el = vm.$el

        this.compile(this.$el)
    }

    // 编译函数
    compile (el) {
        let childNodes = el.childNodes
        Array.from(childNodes).forEach(node => {
            if (this.isTextNode(node)){
                this.compileText(node)
            } else if (this.isElementNode(node)) {
                this.compileElement(node)
            } 

            // 判断node是否存在childNodes节点 如果有就递归调用compile
            if (node.childNodes && node.childNodes.length){
                this.compile(node)
            }
        })
    }

    // 解析element中的指令
    compileElement (node) {
        let attrs = node.attributes
        Array.from(attrs).forEach(attr => {
            let attrName = attr.name
            if(this.isDirective(attrName)){
                attrName = attrName.substr(2)
                let key = attr.value
                this.update(node, key, attrName)    
            }

        })
    }

    // 更新函数
    update (node, key, attrName) {
        // console.log(attrName)
        if (this.isEveneHandle(attrName)) {
            let eventType = attrName.split(':')[1]
            console.log(this.$vm[key])
            this.onUpdate(node, key, this.$vm[key], eventType)
        } else {
            let updateFn = this[attrName+"Update"]
            updateFn && updateFn.call(this, node, key, this.$vm[key])
        }
    }

    // v-text
    textUpdate (node, key, value) {
        node.textContent = value
        new Watcher(this.$vm, key, value => {
            node.textContent = value
        })
    }

    // v-model
    modelUpdate (node, key, value) {
        node.value = value
        new Watcher(this.$vm, key, value => {
            node.value = value
        } )

        node.addEventListener('input', () => {
            this.$vm[key] = node.value
        })
    }

    // v-html
    htmlUpdate (node, key, value) {
        node.innerHTML = value

        new Watcher(this.$vm, key, value => {
            node.innerHTML = value
        })
    }

    // v-on
    onUpdate (node, key, value, eventType) {
        node.addEventListener(eventType,value)

        new Watcher(this.$vm, key, newFn => {
            // 移除上一个eventListener
            node.removeEventListener(eventType, value)
            value = newFn
            node.addEventListener(eventType, newFn)
        })
    }

    // 是否是指令
    isDirective (attrName) {
        return attrName.startsWith('v-')
    }

    // 判断是否是v-on指令
    isEveneHandle (attrName) {
        return attrName.startsWith('on')
    }

    // 解析差值表达式
    compileText (node) {
        let textContent = node.textContent
        let reg = /\{\{(.+?)\}\}/
        if(reg.test(textContent)){
            let key = RegExp.$1.trim()
            node.textContent = this.$vm[key]

            new Watcher(this.$vm, key, value => {
                node.textContent = value
            })
        }
    }

    // 判断是否是文本节点
    isTextNode (node) {
        return node.nodeType === 3
    }

    isElementNode (node) {
        return node.nodeType === 1
    }



}